package com.cyj.dream.admin.controller.admin.system;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cyj.dream.admin.model.request.SysUserQueryRequest;
import com.cyj.dream.admin.model.system.SysDepartment;
import com.cyj.dream.admin.model.system.SysUser;
import com.cyj.dream.admin.service.system.SysDepartmentService;
import com.cyj.dream.admin.service.system.SysUserService;
import com.cyj.dream.core.aspect.annotation.ResponseResult;
import com.cyj.dream.core.aspect.annotation.log.LogRecord;
import com.cyj.dream.core.aspect.enums.OperatorType;
import com.cyj.dream.core.constant.Constant;
import com.cyj.dream.core.constant.enums.ResultCode;
import com.cyj.dream.core.constant.pagemodel.PageParam;
import com.cyj.dream.core.constant.users.BasicInfoSelect;
import com.cyj.dream.core.constant.users.UserContext;
import com.cyj.dream.core.constant.users.UserInfoDTO;
import com.cyj.dream.core.exception.BizException;
import com.cyj.dream.core.util.IsEmptyUtils;
import com.cyj.dream.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: 系统用户模块控制器
 * @BelongsProject: fckj-restaurant
 * @BelongsPackage: com.fckj.fckjrestaurant.controller.admin.systems
 * @Author: ChenYongJia
 * @CreateTime: 2021-04-21 10:35
 * @Email: chen87647213@163.com
 * @Version: 1.0
 */
@Slf4j
@RestController
/** 添加 @ResponseResult 注解调用统一结果返回处理方法 */
@ResponseResult
@Api(value = "user", tags = "用户模块")
@RequestMapping(value = "/pc/user", name = "用户模块")
public class SysUserController {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysDepartmentService sysDepartmentService;

    /**
     * 分页查询用户信息
     *
     * @param pageParam 用户信息入参请求信息
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @date 2021/4/21 10:44
     * @author ChenYongJia
     * @version 1.0
     */
    @ApiOperation(value = "分页查询用户信息", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageParam", value = "系统用户查询request", dataType = "PageParam<SysUserQueryRequest>", required = true)
    })
    @LogRecord(title = "分页查询用户信息", operatetype = OperatorType.SELECT)
    @RequestMapping(value = "/selectSysUser", name = "分页查询用户信息", method = RequestMethod.POST)
    public Map<String, Object> selectSysUser(@RequestBody PageParam<SysUserQueryRequest> pageParam) {
        log.info("进入分页查询用户信息方法控制器，参数为 pageParam：{}", JSONObject.toJSONString(pageParam));
        if (IsEmptyUtils.isEmpty(pageParam.getPageNum()) || IsEmptyUtils.isEmpty(pageParam.getPageSize())) {
            log.error("出现错误：方法执行失败失败！参数为空，请检查参数后重新提交！");
            throw new BizException(ResultCode.PARAM_NOT_COMPLETE);
        }

        Map<String, Object> map = new HashMap<>(Constant.INITIAL_CAPACITY);

        IPage<SysUser> sysUserList = sysUserService.list(pageParam);
        List<SysUser> list = sysUserList.getRecords();
        if (!IsEmptyUtils.isEmpty(list)) {
            list.stream().forEach(item -> {
                item.setUserPassword("");
                if(item.getSysUserInfoDepartmentId() != null && item.getSysUserInfoDepartmentId() != 0){
                    SysDepartment sysDepartment = sysDepartmentService.selectSysDepartmentBySysDepartmentId(item.getSysUserInfoDepartmentId());
                    if(!IsEmptyUtils.isEmpty(sysDepartment)){
                        // 设置部门名称  item.setSysUserInfoDepartmentName(sysDepartment.getSysDepartmentName());
                    }
                }
            });
            sysUserList.setRecords(list);
        }

        map.put("list", sysUserList);
        return map;
    }

    /**
     * 查询系统全部用户信息--用于下拉框
     *
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @date 2021/4/21 10:44
     * @author ChenYongJia
     * @version 1.0
     */
    @AnonymousAccess
    @ApiOperation(value = "查询系统全部用户信息--用于下拉框", httpMethod = "GET")
    @LogRecord(title = "查询系统全部用户信息--用于下拉框", operatetype = OperatorType.SELECT)
    @RequestMapping(value = "/findAllSysUser", name = "查询系统全部用户信息--用于下拉框", method = RequestMethod.GET)
    public Map<String, Object> findAllSysUser() {
        log.info("进入查询系统全部用户信息--用于下拉框方法控制器");
        Map<String, Object> map = new HashMap<>(Constant.INITIAL_CAPACITY);

        map.put("list", sysUserService.findAll());
        return map;
    }

    /**
     * 添加用户详情信息
     *
     * @param sysUser 用户信息
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @date 2021/4/21 10:44
     * @author ChenYongJia
     * @version 1.0
     */
    @ApiOperation(value = "添加用户详情信息", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sysUser", value = "用户详情对象", dataType = "SysUser", required = true)
    })
    @LogRecord(title = "添加用户详情信息", operatetype = OperatorType.INSERT)
    @RequestMapping(value = "/addUserInfo", name = "添加用户信息", method = RequestMethod.POST)
    public Map<String, Object> addUserInfos(@RequestBody SysUser sysUser) {
        log.info("进入添加用户详情信息方法控制器，参数为 sysUser：{}", JSONObject.toJSONString(sysUser));
        Map<String, Object> map = new HashMap<>(Constant.INITIAL_CAPACITY);
        if (IsEmptyUtils.isEmpty(sysUser.getSysUserBirthday()) || IsEmptyUtils.isEmpty(sysUser.getSysUserEmail())
                || IsEmptyUtils.isEmpty(sysUser.getUsername())
                || IsEmptyUtils.isEmpty(sysUser.getSysUserPhone())) {
            log.error("出现错误：方法执行失败失败！参数为空，请检查参数后重新提交！");
            throw new BizException(ResultCode.PARAM_NOT_COMPLETE);
        }

        map.put("info", sysUserService.addUserInfo(sysUser));
        return map;
    }

    /**
     * 根据用户id查询用户
     *
     * @param sysUserId 用户id
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @date 2021-5-19 14:24:37
     * @author ChenYongJia
     * @version 1.0
     */
    @ApiOperation(value = "根据用户id查询用户", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sysUserId", value = "用户id", dataType = "Long", required = true)
    })
    @LogRecord(title = "根据用户id查询用户", operatetype = OperatorType.SELECT)
    @RequestMapping(value = "/findBySysUserId", name = "根据用户id查询用户", method = RequestMethod.GET)
    public Map<String, Object> findBySysUserId(Long sysUserId) {
        log.info("进入根据用户id查询用户方法控制器，参数为 sysUser：{}", sysUserId);
        Map<String, Object> map = new HashMap<>(Constant.INITIAL_CAPACITY);
        if (IsEmptyUtils.isEmpty(sysUserId)) {
            log.error("出现错误：方法执行失败失败！参数为空，请检查参数后重新提交！");
            throw new BizException(ResultCode.PARAM_NOT_COMPLETE);
        }

        map.put("info", sysUserService.findBySysUserId(sysUserId));
        return map;
    }

    /**
     * 修改用户详情信息
     *
     * @param userInfo 用户信息
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @date 2021/4/21 10:49
     * @author ChenYongJia
     * @version 1.0
     */
    @ApiOperation(value = "修改用户详情信息", httpMethod = "PUT")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userInfo", value = "用户详情对象信息", dataType = "SysUser", required = true)
    })
    @LogRecord(title = "修改用户详情信息", operatetype = OperatorType.UPDATE)
    @RequestMapping(value = "/updUserInfo", name = "修改用户详情信息", method = RequestMethod.PUT)
    public Map<String, Object> updUserInfo(@RequestBody SysUser userInfo) {
        log.info("进入修改用户详情信息方法控制器，参数为 userInfo：{}", userInfo);
        Map<String, Object> map = new HashMap<>(Constant.INITIAL_CAPACITY);
        if (IsEmptyUtils.isEmpty(userInfo.getDreamId())) {
            log.error("出现错误：方法执行失败失败！参数为空，请检查参数后重新提交！");
            throw new BizException(ResultCode.PARAM_NOT_COMPLETE);
        }
        map.put("info", sysUserService.updateSysUserCloud(userInfo));
        return map;
    }

    /**
     * 解锁和锁定用户
     *
     * @param userInfo 用户信息
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @date 2021/4/21 10:49
     * @author ChenYongJia
     * @version 1.0
     */
    @ApiOperation(value = "解锁和锁定用户", httpMethod = "PUT")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userInfo", value = "用户详情对象信息", dataType = "SysUser", required = true)
    })
    @LogRecord(title = "解锁和锁定用户", operatetype = OperatorType.UPDATE)
    @RequestMapping(value = "/updUserInfoLock", name = "解锁和锁定用户", method = RequestMethod.PUT)
    public Map<String, Object> updUserInfoLock(@RequestBody SysUser userInfo) {
        log.info("进入解锁和锁定用户方法控制器，参数为 userInfo：{}", userInfo);
        Map<String, Object> map = new HashMap<>(Constant.INITIAL_CAPACITY);
        // 用户是否锁定（0 未锁定 1 已锁定）
        if (IsEmptyUtils.isEmpty(userInfo.getDreamId()) || IsEmptyUtils.isEmpty(userInfo.getSysUserIsLock())) {
            log.error("出现错误：方法执行失败失败！参数为空，请检查参数后重新提交！");
            throw new BizException(ResultCode.PARAM_NOT_COMPLETE);
        }

        map.put("info", sysUserService.updateSysUserCloud(userInfo));
        return map;
    }

    /**
     * 删除用户详情信息
     *
     * @param sysUser 用户信息
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @date 2021/4/21 10:45
     * @author ChenYongJia
     * @version 1.0
     */
    @ApiOperation(value = "删除用户详情信息", httpMethod = "DELETE")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sysUser", value = "用户信息", dataType = "List<SysUser>", required = true)
    })
    @LogRecord(title = "删除用户详情信息", operatetype = OperatorType.DELETE)
    @RequestMapping(value = "/delUserInfo", name = "删除用户详情信息", method = RequestMethod.DELETE)
    public Map<String, Object> delUserInfo(@RequestBody List<SysUser> sysUser) {// 有待修订
        log.info("进入删除用户详情信息方法控制器，参数为 sysUserIdList：{}", JSONObject.toJSONString(sysUser));
        Map<String, Object> map = new HashMap<>(Constant.INITIAL_CAPACITY);
        if (IsEmptyUtils.isEmpty(sysUser)) {
            log.error("出现错误：方法执行失败失败！参数为空，请检查参数后重新提交！");
            throw new BizException(ResultCode.PARAM_NOT_COMPLETE);
        }

        map.put("info", sysUserService.delUserInfo(sysUser));
        return map;
    }

    /**
     * 根据token获取用户信息（根据 key 去 Redis 获取 value）
     *
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @date 2021/4/21 12:02
     * @author ChenYongJia
     * @version 1.0
     */
    @ApiOperation(value = "根据token获取用户信息", httpMethod = "GET")
    @LogRecord(title = "根据token获取用户信息", operatetype = OperatorType.SELECT)
    @RequestMapping(value = "/getUserInfoByToken", name = "根据token获取用户信息", method = RequestMethod.GET)
    public Map<String, Object> getUserInfoByToken() {
        log.info("根据key去Redis获取value");
        UserInfoDTO userInfoDTO = UserContext.get();
        Map<String, Object> map = new HashMap<>(Constant.INITIAL_CAPACITY);
        map.put("value", userInfoDTO);
        return map;
    }

    /**
     * 根据token退出登录（根据 key 去 Redis 删除 value）所有key通用
     *
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @date 2021/4/21 12:02
     * @author ChenYongJia
     * @version 1.0
     */
    @ApiOperation(value = "根据key去Redis删除value", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "前端用户登录后存储的 token", dataType = "String", required = true)
    })
    @LogRecord(title = "根据key去Redis删除value", operatetype = OperatorType.SELECT)
    @RequestMapping(value = "/loginOutByToken", name = "根据key去Redis删除value", method = RequestMethod.GET)
    public Map<String, Object> loginOutByToken() {
        log.info("根据key去Redis删除value");

        // 获取当前请求 request 上下文信息
        String tokenHeader = BasicInfoSelect.getHeaderToken();

        Map<String, Object> map = new HashMap<>(Constant.INITIAL_CAPACITY);
        Object objectTokenValue = sysUserService.loginOutByToken(tokenHeader);
        if (objectTokenValue.toString().isEmpty()) {
            throw new BizException(ResultCode.USER_TOKEN_IS_INVALID);
        } else {
            map.put("value", objectTokenValue);
            return map;
        }
    }

    /**
     * 获取登陆后的用户信息DTO数据
     *
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @date 2021/4/21 12:02
     * @author ChenYongJia
     * @version 1.0
     */
    @ApiOperation(value = "获取登陆后的用户信息DTO数据", httpMethod = "GET")
    @LogRecord(title = "获取登陆后的用户信息DTO数据", operatetype = OperatorType.SELECT)
    @RequestMapping(value = "/loginByUserInfoDTO", name = "获取登陆后的用户信息DTO数据", method = RequestMethod.GET)
    public Map<String, Object> loginByUserInfoDTO() {
        log.info("获取登陆后的用户信息DTO数据");

        Map<String, Object> map = new HashMap<>(Constant.INITIAL_CAPACITY);

        UserInfoDTO userInfoDTO = UserContext.get();
        if (IsEmptyUtils.isEmpty(userInfoDTO)) {
            throw new BizException(ResultCode.USER_TOKEN_IS_INVALID);
        } else {
            map.put("userInfoDTO", userInfoDTO);
            return map;
        }
    }

}
